import pygame,sys,os
from random import randint,choice
from spritesheet import SpriteSheet
from enemy import Enemy

# initialize pygame
pygame.init()

# game window
screen_width = 400
screen_height = 600

# create game window
screen = pygame.display.set_mode((screen_width,screen_height))
pygame.display.set_caption('Jumpy')

# set frame rate
clock = pygame.time.Clock()
fps = 60

# game variables
SCROLL_THRESH = 200
gravity = 1
MAX_PLATFORMS = 10
scroll = 0
bg_scroll = 0
game_over = False
score = 0
score_s = 0
fade_counter = 0

# color
PANEL = (184,66,66)

# font
font_small = pygame.font.SysFont('Lucida Sans', 20)
font_big = pygame.font.SysFont('Lucida Sans', 24)

# load images
jumpy_image = pygame.image.load('../graphics/player.png').convert_alpha()
bg_image = pygame.image.load("../graphics/bg.png").convert_alpha()
platform_image = pygame.image.load("../graphics/layer.png").convert_alpha()

# enemy spritesheet
enemy_image = pygame.image.load('../graphics/enemy.png').convert_alpha()
enemy_sheet = SpriteSheet(enemy_image)

# stop
stop = False
# show character card
show = True

# function for outputting text onto the screen
def draw_text(text,font,text_col,x,y):
    img = font.render(text, True, text_col) 
    screen.blit(img,(x,y))

#function for drawing info panel
def draw_panel():
    pygame.draw.rect(screen,PANEL,(0,0,screen_width,30))
    pygame.draw.line(screen,'white', (0,30),(screen_width,30), 2)
    draw_text('SCORE:' + str(score), font_small, 'white', 0, 0)

# function for drawing th background
def draw_bg(bg_scroll):
    screen.blit(bg_image,(0, 0 + bg_scroll))
    screen.blit(bg_image,(0, -600 + bg_scroll))

def show_charactercard(x,y):
    waiting = True
    waited_time = pygame.time.get_ticks()
    while waiting:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
        draw_text('Name',font_big,'white',x,y)
        pygame.display.update()
        clock.tick(15)
        if pygame.time.get_ticks() - waited_time > 2000:
            waiting = False


# player class
class Player:
    def __init__(self,x,y):
        self.image = pygame.transform.scale(jumpy_image,(32,32))
        self.width = 32
        self.height = 32
        self.rect = pygame.Rect(0,0,self.width,self.height)
        self.rect.center = (x,y)
        self.vel_y = 0
        self.flip = False

    def move(self):
        # reset variables
        scroll = 0
        dx = 0
        dy = 0

        # process keypresses
        key = pygame.key.get_pressed()
        if key[pygame.K_LEFT]:
            dx -= 8
            self.flip = True
        if key[pygame.K_RIGHT]:
            dx += 8
            self.flip = False

        # gravity
        self.vel_y += gravity
        dy += self.vel_y

        # check left_and_right_edge
        if self.rect.left + dx < 0:
            dx = -self.rect.left
        if self.rect.right +dx > screen_width:
            dx = screen_width - self.rect.right

        # check collision with platforms
        for platform in platform_group:
            # collision in the y collision:
            if platform.rect.colliderect(self.rect.x,self.rect.y + dy,self.width,self.height):
                # check if above platform
                if self.rect.bottom < platform.rect.centery:
                    if self.vel_y > 0: # falling
                        self.rect.bottom = platform.rect.top
                        dy = 0
                        self.vel_y = -20

        # check top and scroll
        if self.rect.top <= SCROLL_THRESH:
            # if player is jumping
            if self.vel_y < 0:
                scroll = -dy
        
        # update rect pos
        self.rect.x += dx
        self.rect.y += dy + scroll

        # update masks
        self.mask = pygame.mask.from_surface(self.image)

        return scroll

    def draw(self):
        screen.blit(pygame.transform.flip(self.image,self.flip,False),(self.rect.x,self.rect.y))

class Platform(pygame.sprite.Sprite):
    def __init__(self,x,y,width,moving):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.transform.scale(platform_image,(width,10))
        self.moving = moving
        self.move_counter = randint(0,50)
        self.direction = choice([-1,1])
        self.speed = randint(1,2)
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y

    def update(self,scroll):
        # update platform side to side if it is a moving platform
        if self.moving == True:
            self.move_counter += 1
            self.rect.x += self.direction * self.speed

        # change platform direction if it has moved fully or hit the edge
        if self.move_counter >= 100 or self.rect.left < 0 or self.rect.right > screen_width:
            self.direction *= -1
            self.move_counter = 0

        # update platform's vertical position
        self.rect.y += scroll

        # check if platform has gone offf the screen
        if self.rect.top > screen_height:
            self.kill()

# player    
jumpy = Player(screen_width // 2, screen_height -150)

#create sprite groups
platform_group = pygame.sprite.Group()
enemy_group = pygame.sprite.Group()

# create starting platforms
platform = Platform(screen_width // 2 - 50 ,screen_height - 50, 100, False)
platform_group.add(platform)

# game loop
run = True
while run:
    clock.tick(fps)
    # check the position of the enemy
    if show:
        for enemy in enemy_group:
            if enemy.direction == 1 and enemy.rect.x >= screen_width/2:
                show_charactercard(enemy.rect.left, enemy.rect.top-30)
                show = False
            if enemy.direction == -1 and enemy.rect.x <= screen_width/2:
                show_charactercard(enemy.rect.left, enemy.rect.top-30)
                show = False  

    if game_over == False and score < 500:
        scroll = jumpy.move() # return and give the value to scroll

        # draw background
        bg_scroll += scroll
        if bg_scroll >= 600:
            bg_scroll = 0
        draw_bg(bg_scroll)

        # generate platforms
        if len(platform_group) < MAX_PLATFORMS:
            p_w = randint(50,80)
            p_x = randint(0,screen_width - p_w) # limited by screen width
            p_y = platform.rect.y - randint(80,120)# the previous platform
            p_type = randint(1,2)
            if p_type == 1 and score > 100:
                p_moving = True
            else:
                p_moving = False
            platform = Platform(p_x ,p_y, p_w, p_moving)
            platform_group.add(platform)

        # update platforms
        platform_group.update(scroll)

        # generate enemy
        if len(enemy_group) == 0 and score > 150:
            enemy = Enemy(screen_width, 100, enemy_sheet, 1)
            enemy_group.add(enemy)

        # update enemy
        enemy_group.update(scroll, screen_width)
                  
        # update score
        if score >= 0:
            score_s += scroll
            score = score_s // 10

        # draw sprites
        platform_group.draw(screen)
        enemy_group.draw(screen)
        jumpy.draw()

        # draw panel
        draw_panel()

        # check game over
        if jumpy.rect.top > screen_height:
            game_over = True

        # check for collision sith enemy:
        if pygame.sprite.spritecollide(jumpy, enemy_group, False): # rectangle collision
            if pygame.sprite.spritecollide(jumpy, enemy_group, False,pygame.sprite.collide_mask):#more accurate collision
                game_over = True
    # lose screen
    elif game_over == True and score < 500:
        if fade_counter < screen_width / 2:
            fade_counter += 5
            pygame.draw.rect(screen, 'black', (0, 0, fade_counter, screen_height))
            pygame.draw.rect(screen, 'black', (screen_width - fade_counter, 0, screen_width, screen_height))
        else: 
            draw_text('TRY AGAIN!',font_big,'white',130,200)
            draw_text('SCORE:' + str(score),font_big,'white',130,250)
            draw_text('PRESS SPACE TO EXIT',font_big,'white',70,300)
            draw_text('PRESS ENTER TO PLAY AGAIN',font_big,'white',40,350)
            key = pygame.key.get_pressed()
            if key[pygame.K_SPACE]:
                pygame.quit()
                quit()
            elif key[pygame.K_RETURN]:
                # reset
                game_over = False
                score = 0
                score_s = 0
                scroll = 0
                fade_counter = 0

                # reposition
                jumpy.rect.center = (screen_width // 2, screen_height - 150)

                # reset enemy
                enemy_group.empty()

                # reset platforms
                platform_group.empty()

                # create starting platforms
                platform = Platform(screen_width // 2 - 50 ,screen_height - 50, 100, False)
                platform_group.add(platform)
            if key[pygame.K_u] and key[pygame.K_c] and key[pygame.K_a] and key[pygame.K_s]:
                # reset
                game_over = False
                score = score
                score_s = score_s
                scroll = scroll
                fade_counter = 0

                # reposition
                jumpy.rect.center = (screen_width // 2, screen_height - 300)

                # reset enemy
                enemy_group.empty()

                # reset platforms
                platform_group.empty()

                # create starting platforms
                platform = Platform(screen_width // 2 - 50 ,screen_height - 50, 100, False)
                platform_group.add(platform)
    # win screen
    elif  score >= 500:   
        game_over == True
        if fade_counter < screen_width / 2:
            fade_counter += 5
            pygame.draw.rect(screen, 'black', (0, 0, fade_counter, screen_height))
            pygame.draw.rect(screen, 'black', (screen_width - fade_counter, 0, screen_width, screen_height))
        else: 
            draw_text('YOU WIN!',font_big,'yellow',130,200)
            draw_text('SCORE:' + str(score),font_big,'white',130,250)
            draw_text('PRESS SPACE TO EXIT',font_big,'white',70,300)
            draw_text('PRESS ENTER TO PLAY AGAIN',font_big,'white',40,350)
            key = pygame.key.get_pressed()
            if key[pygame.K_SPACE]:
                pygame.quit()
                sys.exit()
            elif key[pygame.K_RETURN]:
                pygame.quit()
                os.system('cd ../../level_7/mainpy & python main.py')
                quit()
            
    # key control
    key = pygame.key.get_pressed()
    if key[pygame.K_p]:
        stop = True
    while stop:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
        key = pygame.key.get_pressed()
        if key[pygame.K_z]:
            stop = False

    # event handler
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    # update display window
    pygame.display.update()

pygame.quit()